package com.example.qrcodeservice.controller;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets; // 添加字符集支持
import java.util.Map;
import javax.imageio.ImageIO;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.util.HashMap;

/**
 * QrCodeController类负责处理二维码相关的API请求。
 */
@RestController
public class QrCodeController {

    /**
     * 处理GET请求，返回服务健康状态。
     * @return 200 OK
     */
    @GetMapping("/api/health")
    public ResponseEntity<String> healthCheck() {
        return ResponseEntity.ok("200 OK");
    }

    /**
     * 处理GET请求，生成并返回一个250x250像素的白色PNG图像。
     * @return 包含图像的字节数组
     * @throws IOException 如果图像写入失败
     */
    @GetMapping("/api/qrcode")
    public ResponseEntity<?> getImage(
            @RequestParam String contents,
            @RequestParam(required = false, defaultValue = "250") int size,
            @RequestParam(required = false, defaultValue = "L") String correction,
            @RequestParam(required = false, defaultValue = "png") String type) {
        
        // 检查内容参数
        if (contents == null || contents.trim().isEmpty()) {
            return ResponseEntity.badRequest().body(Collections.singletonMap("error", "Contents cannot be null or blank"));
        }
        
        // 检查尺寸参数
        if (size < 150 || size > 350) {
            return ResponseEntity.badRequest().body(Collections.singletonMap("error", "Image size must be between 150 and 350 pixels"));
        }
        
        // 检查纠正级别参数
        List<String> supportedCorrections = Arrays.asList("L", "M", "Q", "H");
        if (!supportedCorrections.contains(correction.toUpperCase())) {
            return ResponseEntity.badRequest().body(Collections.singletonMap("error", "Permitted error correction levels are L, M, Q, H"));
        }
        
        // 检查类型参数
        List<String> supportedTypes = Arrays.asList("png", "jpeg", "gif");
        if (!supportedTypes.contains(type.toLowerCase())) {
            return ResponseEntity.badRequest().body(Collections.singletonMap("error", "Only png, jpeg and gif image types are supported"));
        }
        
        // 生成二维码
        try {
            QRCodeWriter writer = new QRCodeWriter();
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.valueOf(correction.toUpperCase()));
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 添加UTF-8字符集提示
            // 使用UTF-8编码处理中文内容
            BitMatrix bitMatrix = writer.encode(new String(contents.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8), 
                BarcodeFormat.QR_CODE, size, size, hints);
            BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
            
            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("image/" + type));
            
            // 将图像写入字节数组输出流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, type, baos);
            
            return ResponseEntity.ok().headers(headers).body(baos.toByteArray());
        } catch (WriterException | IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error generating QR code");
        }
    }
}
